package com.qz.mos.service;

import com.alibaba.fastjson.JSONObject;
import com.qz.mos.entity.RestData;
import com.qz.mos.entity.RestDataMD5;
import com.qz.mos.jpa.RestDataJpa;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.data.domain.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ResponseStatusException;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.http.HttpStatus.NOT_FOUND;

@Slf4j
@Service
public class RestDataService {
    @Autowired
    RestDataJpa restDataJpa;
    /**
     * get请求查找参数
     * @param request
     * @return
     */
    public void getData(HttpServletRequest request, HttpServletResponse response,ResourceHttpMessageConverter resourceHttpMessageConverter) throws IOException {
        List <RestData> restData = getRestData( request );
        RestData restData1 = restData.get( 0 );
        response.setContentType( restData1.getRespType() );

        ServletServerHttpResponse outputMessage = new ServletServerHttpResponse( response );
        String[] split = restData1.getRespType().split( "/" );
        MediaType mediaType = new MediaType(  split[0],split[1] );
        ByteArrayResource byteArrayResource = new ByteArrayResource( restData1.getResBody().getPic() );
        resourceHttpMessageConverter.write( byteArrayResource, mediaType, outputMessage );
    }

    private Object respObject(List <Object> collect) {
        if(collect.isEmpty()){
            log.warn( "========请配置响应参数=========" );
        }
        int size = collect.size();
        if(size==0){
            throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
        }
        if(size>=1){
            return collect.get( 0 );
        }

        return  collect;
    }

    private Object restObj(RestData e) {
        RestDataMD5 resBody = e.getResBody();
        if(StringUtils.isEmpty( resBody ))return null;



        String data = resBody.getData();
        boolean validObject = JSONObject.isValidObject( data );
        if(validObject){
            return JSONObject.parseObject(  data);
        }
        if(JSONObject.isValidArray(data  )){
            return JSONObject.parseArray( data );
        }
        return data;


    }



    private List <RestData> getRestData(HttpServletRequest request) {
        String requestURI = getRequestURI( request );
        String METHOD = request.getMethod();
        log.info( "url:{}" ,requestURI);
        log.info( "请求方式:{}" ,METHOD);
        RestData restData = new RestData();
        restData.setMethod( METHOD );
        restData.setUrl( requestURI );
        Sort creatTime = Sort.by( Sort.Direction.DESC, "creatTime" );
        PageRequest of = PageRequest.of( 0, 10, creatTime );
        Example <RestData> of1 = Example.of( restData );
        List <RestData> all = restDataJpa.findAll( of1, creatTime);

        log.info( "url请求响应结果总数:{}" ,all.size());
        if(all.isEmpty()){
            throw new ResponseStatusException(NOT_FOUND, "Unable to find resource");
        }
        return all;
    }

    private String getRequestURI(HttpServletRequest request) {
        return request.getRequestURI();
    }

    /**
     * post 查询参数
     * @param request
     * @return
     */
    public Object postData(HttpServletRequest request) {
        List <RestData> restData = getRestData( request);
        List <Object> collect = restData.stream()
                                .map( e-> restObj(e)
                ).collect( Collectors.toList() );
        return respObject( collect );
    }



    /**
     *
     * @param httpServletRequest
     * @return
     */
    public String getBody(HttpServletRequest httpServletRequest) {
        String s=null;
        // 获取内容长度
        int length = httpServletRequest.getContentLength();
        // 新建缓存存放读取数据
        byte[] buffer = new byte[length];
        ServletInputStream in = null;

        try {
            in = httpServletRequest.getInputStream();
            in.read(buffer, 0, length);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            s = new String( buffer, "UTF-8" );
            log.info( "请求内容:{}",s );
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return s;
    }




    /**
     * 创建
     * @param request
     * @return
     */
    public RestData create(RestData request) {


        return restDataJpa.save( request );
    }




    public RestData put(RestData request) {
        String id = request.getId();
        RestData restData = restDataJpa.findById( id ).orElseGet( RestData::new );
        BeanUtils.copyProperties( request,restData );
        return this.create(restData);
    }

    /**
     * 查询操作
     * @param restData
     * @param pageable
     * @return
     */
    public Page<RestData> list(RestData restData, Pageable pageable) {
        return restDataJpa.findAll( pageable );
    }

    public void delData(RestData request) {
        restDataJpa.delete(request  );
    }



    public void save(RestData restData) {
        Date creatTime = new Date();
        restData.setGroupMos( "离线缓存" );
        restData.setName( LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) );
        restData.setCreatTime( creatTime );
        RestData save = restDataJpa.save( restData );

    }


    public List <RestData> getData(String requestURI, String METHOD, HttpHeaders
            httpHeaders,MultiValueMap <String, String> queryParams) {
        RestData restData = new RestData();
        boolean empty = queryParams.isEmpty();
        if(!empty){
            restData.setBody( JSONObject.toJSONString(  queryParams) );
        }
        //restData.setHeadersData( JSON.toJSONString( httpHeaders ) );
        restData.setMethod( METHOD );
        restData.setUrl( requestURI );
        Sort creatTime = Sort.by( Sort.Direction.DESC, "creatTime" );
        PageRequest of = PageRequest.of( 0, 10, creatTime );
        Example <RestData> of1 = Example.of( restData );
        List <RestData> all = restDataJpa.findAll( of1, creatTime);
        return all;
    }

    public List <RestData> getData(String requestURI, String METHOD,HttpHeaders httpHeaders,  MultiValueMap<String,String> queryParams, String bodyString) {
        RestData restData = new RestData();
        boolean empty = queryParams.isEmpty();
        if(!empty){
            restData.setQuery( JSONObject.toJSONString(  queryParams) );
        }
        if(bodyString!=null){
            restData.setBody(  bodyString);
        }
        //restData.setHeadersData( JSON.toJSONString( httpHeaders ) );
        restData.setMethod( METHOD );
        restData.setUrl( requestURI );
        Sort creatTime = Sort.by( Sort.Direction.DESC, "creatTime" );
        PageRequest of = PageRequest.of( 0, 10, creatTime );
        Example <RestData> of1 = Example.of( restData );
        List <RestData> all = restDataJpa.findAll( of1, creatTime);
        return all;
    }
}
